package ejb;

import interfaces.SolicitarCotizacion;
import interfaces.TagsXML;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import utils.NamingUtil;

import entitys.Cliente;
import entitys.Factura;
import entitys.ItemFactura;
import entitys.ItemRemito;
import entitys.ItemSolicitudCompra;
import entitys.Remito;
import entitys.Rodamiento;
import entitys.SolicitudCompra;

/**
 * Message-Driven Bean implementation class for: GenerarFactura
 *
 */
@MessageDriven(
		activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
							 @ActivationConfigProperty(propertyName="destination",propertyValue="queue/colaRemito")})
public class GenerarFacturaBean implements MessageDrivenBean,MessageListener {
	@PersistenceContext(unitName = "OficinaVentas")
	private EntityManager manager;
	
    public GenerarFacturaBean() {
        // TODO Auto-generated constructor stub
    }
	
	/**
     * @see MessageListener#onMessage(Message)
     */
    @Override
    public void onMessage(Message message) {
    	TextMessage msg = null;
		try {
			if (message instanceof TextMessage) {
				msg = (TextMessage)message;
				procesarXML(msg.getText());
			} else {
				System.out.println("Error en el mensaje recibido");
			}
				
		} catch (JMSException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    private void procesarXML(String xmlRemito){
    	SolicitudCompra oSolCom = getSolicitudCompra(xmlRemito);
    	Factura oFactura = generarFactura(oSolCom);
    	oSolCom.setFactura(oFactura);
    	manager.merge(oSolCom);
    	manager.flush();
    	enviarFactura(getXMLFactura(oSolCom.getFactura()));
    }
    
    private SolicitudCompra getSolicitudCompra(String xmlRemito){
    	SolicitudCompra oSolCom = null;
    	try {
		    SAXBuilder xmlBuilder = new SAXBuilder();
		    Reader in = new StringReader(xmlRemito);
		    Document oDoc = xmlBuilder.build(in);
		    Element root = oDoc.getRootElement();
		    Remito oRemito = new Remito();
		    oRemito.setIdRemito(Integer.parseInt(root.getAttributeValue(TagsXML.NRO_REMITO)));
		    //Cliente oCliente = manager.find(Cliente.class,root.getAttribute(TagsXML.ID_CLIENTE).getValue());
			//oRemito.setCliente(oCliente);
			SimpleDateFormat formatoFecha = new SimpleDateFormat("dd/MM/yyyy");
			oRemito.setFechaEmision(formatoFecha.parse(root.getAttribute(TagsXML.FECHA_EMISION).getValue()));
			oSolCom = manager.find(SolicitudCompra.class,Integer.parseInt(root.getAttribute(TagsXML.ID_SOLICITUD_COMPRA).getValue()));
			List<Element> items = root.getChildren(); 
			for(Element oElem : items){
				ItemRemito oItem = new ItemRemito();
				oItem.setRodamiento(manager.find(Rodamiento.class, oElem.getChild(TagsXML.ID_RODAMIENTO).getTextTrim()));
				oItem.setCantidad(Integer.valueOf(oElem.getChild(TagsXML.CANTIDAD).getTextTrim()));
				oItem.setPrecioUnitario((Float.valueOf(oElem.getChild(TagsXML.PRECIO_UNITARIO).getTextTrim())));
				oItem.setPrecioFinal((Float.valueOf(oElem.getChild(TagsXML.PRECIO_FINAL).getTextTrim())));
				oItem.setCantidad(Integer.valueOf(oElem.getChild(TagsXML.CANTIDAD).getTextTrim()));
				oRemito.addItem(oItem);
			}
			oSolCom.setRemito(oRemito);
		}catch (JDOMException je) {
		    je.printStackTrace();
		}catch (IOException e){
			e.printStackTrace();
		}catch (ParseException e){
			e.printStackTrace();
		}
		return oSolCom;
    }
    
    private String getXMLFactura(Factura oFactura){
    	SimpleDateFormat oFormatoFecha = new SimpleDateFormat("dd/mm/yyyy");

		Element root = new Element(TagsXML.FACTURA);
		root.setAttribute(TagsXML.NRO_FACTURA,String.valueOf(oFactura.getIdFactura()));
		root.setAttribute(TagsXML.FECHA_EMISION,oFormatoFecha.format(oFactura.getFechaEmision()));
		root.setAttribute(TagsXML.SUBTOTAL,String.valueOf(oFactura.getSubTotal()));
		root.setAttribute(TagsXML.TIPO_FACTURA,oFactura.getCliente().getTipoFactura());
		root.setAttribute(TagsXML.PRECIO_IVA,String.valueOf(oFactura.getIva()));
		root.setAttribute(TagsXML.PRECIO_TOTAL,String.valueOf(oFactura.getTotal()));
		
		for (ItemFactura oItemFactura : oFactura.getItems()) {
			Element item = new Element(TagsXML.ITEM_FACTURA);
			Element idRod = new Element(TagsXML.ID_RODAMIENTO);
			idRod.setText(String.valueOf(oItemFactura.getRodamiento().getIdRodamiento()));
			item.addContent(idRod);
			Element cantidad = new Element(TagsXML.CANTIDAD);
			cantidad.setText(String.valueOf(oItemFactura.getCantidad()));
			item.addContent(cantidad);
			Element precioUnitario = new Element(TagsXML.PRECIO_UNITARIO);
			precioUnitario.setText(String.valueOf(oItemFactura.getPrecioUnitario()));
			item.addContent(precioUnitario);
			Element precioFinal = new Element(TagsXML.PRECIO_FINAL);
			precioFinal.setText(String.valueOf(oItemFactura.getPrecioUnitario() * oItemFactura.getCantidad()));
			item.addContent(precioFinal);
			root.addContent(item);
		}
		
		Document oDoc = new Document();
		oDoc.addContent(root);
		XMLOutputter xml = new XMLOutputter();
		return xml.outputString(oDoc);
    }
    
    private Factura generarFactura(SolicitudCompra oSolCom){
    	Remito oRemito = oSolCom.getRemito();
    	Factura oFactura = new Factura();
    	oFactura.setCliente(oSolCom.getCliente());
    	oFactura.setFechaEmision(Calendar.getInstance().getTime());
    	float subtotal = 0;
    	for(ItemRemito oItemRemito : oRemito.getItems()){
    		ItemFactura oItemFactura = new ItemFactura();
    		oItemFactura.setRodamiento(oItemRemito.getRodamiento());
    		oItemFactura.setCantidad(oItemRemito.getCantidad());
    		oItemFactura.setPrecioUnitario(oItemRemito.getPrecioUnitario() + oItemRemito.getPrecioUnitario() / 2);
    		oFactura.addItem(oItemFactura);
    		subtotal = subtotal + oItemFactura.getCantidad() * oItemFactura.getPrecioUnitario();
    	}
    	oFactura.setSubTotal(subtotal);
    	float iva = subtotal * 21 / 100;
    	oFactura.setIva(iva);
    	oFactura.setTotal(subtotal + iva);
    	return oFactura;
    }
    
    private void enviarFactura(String xmlFactura){
    	try {
			InitialContext ctx = NamingUtil.getInitialContext();
			QueueConnectionFactory oFactory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
			Queue queue = (Queue) ctx.lookup("queue/primerQueue2");
			QueueConnection qConnection = oFactory.createQueueConnection();
			QueueSession qSession = qConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
			QueueSender qSender = qSession.createSender(queue);
			TextMessage message = qSession.createTextMessage(xmlFactura);
			qSender.send(message);
		} catch (Exception e) {
			System.out.println("Error al enviar la solicitud al cliente " + e.getStackTrace());
		}
    }

	@Override
	public void ejbRemove() throws EJBException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setMessageDrivenContext(MessageDrivenContext arg0)
			throws EJBException {
		// TODO Auto-generated method stub
		
	}
}
